<template>
  <div class="chat-container">
    <!-- 顶部栏 -->
    <cp-nav-bar :title="contactUser?.username" left-arrow>
      <template #right> <van-icon name="ellipsis" size="24" @click="toUserInfo" /></template>
    </cp-nav-bar>

    <div
      class="message-list"
      :class="isShowEmoji ? 'message-list-active' : 'message-list'"
      ref="messageList"
      @click="noClick"
    >
      <div
        v-for="(message, index) in messages"
        :key="index"
        :class="['message-container', message.isSent ? 'sent' : 'received']"
      >
        <!-- Contact avatar (left side) -->
        <div class="avatar" v-if="!message.isSent">
          <img :src="contactUser.avatar" alt="Contact avatar" />
        </div>

        <div class="message">
          <div class="message-content">
            <p v-if="message.message_type === 0">{{ message.content }}</p>
            <van-image
              v-else-if="message.message_type === 1"
              style="margin-bottom: 3px"
              :src="'http://127.0.0.1:3000' + message.content"
              alt=""
              width="200px"
              fit="scale-down"
              radius="5px"
              @click="showImgAll(message.content)"
            ></van-image>
            <span class="message-time">{{ formatTime(message.timestamp) }}</span>
          </div>
        </div>

        <!-- User avatar (right side) -->
        <div class="avatar self-avatar" v-if="message.isSent">
          <img :src="currentUser.avatar" alt="Your avatar" />
        </div>
      </div>
    </div>

    <div class="message-input" :class="isShowEmoji ? 'message-input-active' : 'message-input'">
      <input
        type="text"
        v-model="newMessage"
        placeholder="请输入内容"
        @keyup.enter="sendMessage"
        enterkeyhint="send"
      />

      <van-icon name="smile-o" size="24" style="margin-right: 10px" @click="showEmojiAction" />
      <van-icon name="add-o" size="24" @click="showFileImgAction" />
    </div>
    <div class="emoji-content" :class="isShowEmoji ? 'emoji-content-active' : 'emoji-content'">
      <Picker
        :data="emojiIndex"
        set="twitter"
        @select="showEmoji"
        :showPreview="false"
        :showSkinTones="false"
        emojiTooltip
        :showSearch="false"
        :i18n="i18n"
        style="width: 100%; height: 100%"
        v-show="active === '1'"
      />
      <div class="img-file-content" v-show="active === '2'">
        <div class="img-file-box">
          <div @click="triggerUpload">
            <cp-icon name="chat-photo-album" class="img-icon"></cp-icon>
            <div class="img-text">照片</div>
            <input type="file" ref="inputImgRef" @input="uploadImg" style="display: none" />
          </div>
        </div>
      </div>
    </div>
    <van-overlay
      :show="show"
      @click="show = false"
      style="display: flex; align-items: center; justify-content: center"
    >
      <van-image :src="currentImg" alt="" width="100%" fit="scale-down" radius="5px"></van-image>
    </van-overlay>
  </div>
</template>

<script setup lang="ts">
import { getChatMessage } from '@/services/chat'
import type { ChatDataMessage } from '@/types/chat'
import type { UserInfo } from '@/types/user'
import { ref, reactive, onMounted, nextTick, onUnmounted } from 'vue'
import { useRoute } from 'vue-router'
import { formatTime } from '@/utils/format'
import { socketService } from '@/utils/socket'
import { cloneDeep } from 'lodash'
import data from 'emoji-mart-vue-fast/data/all.json'
import 'emoji-mart-vue-fast/css/emoji-mart.css'
import { Picker, EmojiIndex } from 'emoji-mart-vue-fast/src'
import { showFailToast } from 'vant'
import axios from 'axios'
import router from '@/router'

const emojiIndex = new EmojiIndex(data)
const i18n = {
  search: '搜索',
  notfound: '未找到表情',
  categories: {
    search: '搜索结果',
    recent: '常用表情',
    smileys: '笑脸与表情',
    people: '人物与身体',
    nature: '动物与自然',
    foods: '食物与饮料',
    activity: '活动',
    places: '旅行与地点',
    objects: '物品',
    symbols: '符号',
    flags: '旗帜',
    custom: '自定义'
  }
}
const active = ref('-1')
const showEmoji = (emoji) => {
  newMessage.value += emoji.native
}

// User data
const contactUser = reactive<UserInfo>({
  id: 0,
  user_id: '',
  avatar: '',
  sex: 0,
  signature: '',
  username: ''
})
const currentUser = reactive<UserInfo>({
  id: 0,
  user_id: '',
  avatar: '',
  sex: 0,
  signature: '',
  username: ''
})

// Refs and reactive state
const messageList = ref<HTMLElement | null>(null)
const newMessage = ref<string>('')
const messages = reactive<ChatDataMessage[]>([])

// Functions
const scrollToBottom = (): void => {
  nextTick(() => {
    if (messageList.value) {
      messageList.value.scrollTop = messageList.value.scrollHeight
    }
  })
}

const getMessage = async () => {
  const route = useRoute()
  const sender_id = route.query.sender_id as string
  const { data } = await getChatMessage(sender_id)
  Object.assign(contactUser, cloneDeep(data.senderInfo))
  Object.assign(currentUser, cloneDeep(data.receiverInfo))
  const newData = data?.messageList.map((item) => {
    return {
      ...item,
      isSent: sender_id !== item.sender_id
    }
  })
  messages.push(...newData)
  nextTick(() => {
    scrollToBottom()
  })
  connectSocket()
}
const toUserInfo = () => {
  router.push(`/userInfo/${contactUser.user_id}`)
}
// 连接 Socket
const connectSocket = () => {
  const userId = currentUser.user_id
  socketService.connect(userId)

  // 监听新消息
  socketService.onMessage((message) => {
    messages.push({
      ...message,
      isSent: false
    })
    scrollToBottom()
  })
}

// 发送消息
const sendMessage = () => {
  if (newMessage.value.trim()) {
    const message = {
      sender_id: currentUser.user_id,
      receiver_id: contactUser.user_id,
      content: newMessage.value,
      timestamp: new Date().toISOString(),
      message_type: 0
    }
    socketService.sendMessage(message)
    newMessage.value = '' // 清空输入框
    messages.push({
      ...message,
      isSent: true
    })
    scrollToBottom()
  }
}

const isShowEmoji = ref(false)
//展示表情包面板
const showEmojiAction = () => {
  if (!isShowEmoji.value) {
    isShowEmoji.value = !isShowEmoji.value
    active.value = '1'
    return
  }
  if (isShowEmoji.value && active.value === '2') {
    active.value = '1'
  } else {
    isShowEmoji.value = !isShowEmoji.value
    active.value = '-1'
  }
  nextTick(() => {
    scrollToBottom() // 表情面板展开或收起时，滚动到底部
  })
}
//展示图片上传面版
const showFileImgAction = () => {
  if (!isShowEmoji.value) {
    active.value = '2'
    isShowEmoji.value = !isShowEmoji.value
    return
  }
  if (isShowEmoji.value && active.value === '1') {
    active.value = '2'
  } else {
    isShowEmoji.value = !isShowEmoji.value
    active.value = '-1'
  }
}
const inputImgRef = ref<HTMLInputElement>()
//上传图片
const uploadImg = async (e: Event) => {
  const inputElement = e.target as HTMLInputElement
  if (!(inputElement instanceof HTMLInputElement)) {
    showFailToast('无效的元素')
    return
  }

  if (!inputElement.files || inputElement.files.length === 0) {
    showFailToast('请选择文件')
    return
  }

  const file = inputElement.files[0]
  const allowedTypes = ['image/jpeg', 'image/png', 'image/gif']
  const MAX_SIZE = 5 * 1024 * 1024 // 5MB

  if (!allowedTypes.includes(file.type)) {
    showFailToast('仅支持 JPEG、PNG、GIF 格式的图片')
    return
  }

  if (file.size > MAX_SIZE) {
    showFailToast('文件大小不能超过 5MB')
    return
  }

  const formData = new FormData()
  formData.append('image', file)
  axios
    .post('http://127.0.0.1:3000/chat/upload', formData, {
      headers: {
        'Content-Type': 'multipart/form-data' // 设置请求头
      }
    })
    .then((response) => {
      const message = response.data.data.imagePath
      sendImgMessage(message)
    })
    .catch((error) => {
      console.log(error)
      showFailToast('发送图片失败')
    })
}
const sendImgMessage = (messageContent: string) => {
  const message = {
    sender_id: currentUser.user_id,
    receiver_id: contactUser.user_id,
    content: messageContent,
    timestamp: new Date().toISOString(),
    message_type: 1
  }
  socketService.sendMessage(message)
  messages.push({
    ...message,
    isSent: true
  })
  scrollToBottom()
}
const triggerUpload = () => {
  if (inputImgRef.value) {
    inputImgRef.value.click()
  }
}
const noClick = () => {
  isShowEmoji.value = false
  active.value = '-1'
}
const show = ref(false)
const currentImg = ref('')
const showImgAll = (src: string) => {
  show.value = !show.value
  currentImg.value = 'http://127.0.0.1:3000' + src
}
// Lifecycle hooks
onMounted(() => {
  getMessage()
})

onUnmounted(() => {
  socketService.disconnect()
})
</script>

<style lang="scss">
.chat-container {
  padding-top: 46px;
  background-color: var(--bg-primary);
  height: 100vh;
  box-sizing: border-box;
  font-family:
    -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans',
    'Helvetica Neue', sans-serif;
}

.avatar {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  overflow: hidden;
  flex-shrink: 0;
}

.avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.message-list {
  flex-grow: 1;
  padding: 15px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 15px;
  height: calc(100vh - 140px);
  transition: height 0.3s ease-in-out;
}

.message-container {
  display: flex;
  align-items: flex-end;
  gap: 8px;
  max-width: 85%;
}

.message-container.received {
  align-self: flex-start;
}

.message-container.sent {
  align-self: flex-end;
}

.message {
  min-width: 100px; /* 设置最小宽度 */
  max-width: calc(100% - 48px); /* 保留原有最大宽度 */
}

.message-content {
  padding: 10px 15px;
  border-radius: 18px; /* 统一圆角 */
  position: relative;
}

.message-container.received .message-content {
  background-color: var(--chat-message-bg); /* 调整透明度 */
  border-top-left-radius: 5px;
}

.message-container.sent .message-content {
  background-color: rgba(25, 192, 163, 0.9); /* 调整透明度 */
  border-top-right-radius: 5px;
}

.message-content p {
  margin-bottom: 5px; /* 减少下边距 */
  line-height: 1.4;
  word-break: break-word; /* 长单词自动换行 */
  overflow-wrap: break-word; /* 确保长文本换行 */
}

.message-time {
  position: absolute;
  bottom: 3px;
  right: 10px;
  font-size: 11px;
  color: var(--chat-message-text);
  white-space: nowrap; /* 防止时间戳换行 */
}

.message-input {
  display: flex;
  align-items: center;
  padding: 10px;
  background-color: var(--chat-input-bg);
  border-top: 1px solid #ddd;
  position: fixed;
  width: 100%;
  left: 0;
  bottom: 0px;
  transition: bottom 0.3s ease-in-out;
}
.message-list-active {
  height: calc(100vh - 390px);
}
.message-input-active {
  bottom: 250px;
}
.emoji-content {
  width: 100%;
  height: 0px;
  background-color: #fff;
  position: fixed;
  left: 0;
  bottom: 0;
  transition: height 0.3s ease-in-out;
}
.emoji-content-active {
  height: 250px;
}
.message-input input {
  width: 243px;
  padding: 10px 15px;
  border: none;
  border-radius: 20px;
  margin: 0 10px;
  outline: none;
  font-size: 16px;
  background-color: var(--chat-input-inset);
}

.img-file-content {
  height: 100%;
  width: 100%;
  background: var(--bg-primary);
}
.img-file-box {
  padding: 20px;
  .img-icon {
    font-size: 55px;
  }
  .img-text {
    width: 55px;
    text-align: center;
    color: rgba(102, 102, 102, 1);
    font-size: 14px;
  }
}
</style>
